package com.xhwl.centiotdata.handler.pedestrian.impl;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationFactory;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationHandler;
import com.xhwl.centiotdata.pojo.constant.DaHuaConstant;
import com.xhwl.centiotdata.pojo.dto.dahua.IdentityDaHuaDTO;
import com.xhwl.centiotdata.pojo.dto.dahua.PedestrianRecordDaHuaDTO;
import com.xhwl.centiotdata.pojo.dto.dahua.UserDaHuaDTO;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.enums.pedestrian.OpenUserTypeEnum;
import com.xhwl.centiotdata.service.cent.IAccountCentService;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.service.cent.IPedestrianCentService;
import com.xhwl.centiotdata.suppliersystem.dahua.GeneralDaHuaHandler;
import com.xhwl.centiotdata.suppliersystem.dahua.PedestrianDaHuaHandler;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.pedes.OpenDoorRecordDTO;
import com.xhwl.common.enums.AccessApproachEnum;
import com.xhwl.common.enums.AccessTypeEnum;
import com.xhwl.common.enums.DirectionEnum;
import com.xhwl.common.enums.SourceTypeEnum;
import com.xhwl.common.enums.pedestrian.DoorActionEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.query.cent.sdata.AccountQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/06/ 11:31
 */
@Service
public class PedestrianIntegrationDaHuaHandler extends PedestrianIntegrationHandler {

    @Autowired
    private PedestrianDaHuaHandler pedestrianDaHuaHandler;
    @Autowired
    private IPedestrianCentService pedestrianCentService;
    @Autowired
    private IAccountCentService accountCentService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private IAuthAccountCentService authAccountCentService;

    @Override
    public void afterPropertiesSet() throws Exception {
        PedestrianIntegrationFactory.register(5, this);
    }

    @Override
    public void pullRecord(PedestrianIntegrationConfigDTO configDTO, Integer intervalDays, Date date) {
        // 拉取数据
        List<PedestrianRecordDaHuaDTO> recordDaHuaDTOList = pedestrianDaHuaHandler.pullRecord(configDTO);
        if (CollectionUtils.isEmpty(recordDaHuaDTOList)) {
            return;
        }
        // 转换数据
        List<OpenDoorRecordDTO> openDoorRecordDTOList = this.handleRecord(configDTO, recordDaHuaDTOList);
        // 存储业务中台
        pedestrianCentService.saveBatch(openDoorRecordDTOList);
    }

    @Override
    public ResultJson openDoor(PedestrianIntegrationConfigDTO configDTO, DeviceDTO deviceDTO, DoorActionEnum doorAction) {
        return pedestrianDaHuaHandler.openDoor(configDTO, deviceDTO, doorAction);
    }

    @Override
    public ResultJson createAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        AuthAccountMapping accountMapping = this.createUser(configDTO, pedestrianAuthDTO);
        String openId = accountMapping.getOpenId();
        authAccountCentService.save(configDTO.getProjectId(), pedestrianAuthDTO.getSourceId(),openId,null,configDTO.getProductId());
        pedestrianAuthDTO.setUserOpenId(openId);
        try {
            onSavingAuthCards(authAccountCentService, configDTO, pedestrianAuthDTO);
        } catch (Exception e) {
            // 保存转换卡号数据失败
        }
        return ResultJson.success();
    }


    @Override
    public ResultJson updateAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {

        return super.updateAuth(configDTO, pedestrianAuthDTO);
    }

    @Override
    public ResultJson deleteAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        return super.deleteAuth(configDTO, pedestrianAuthDTO);
    }

    private List<OpenDoorRecordDTO> handleRecord(PedestrianIntegrationConfigDTO configDTO, List<PedestrianRecordDaHuaDTO> recordDaHuaDTOList) {
        return recordDaHuaDTOList.stream()
                .filter(recordDaHuaDTO -> !DaHuaConstant.DOOR_EVENT_LIST.contains(recordDaHuaDTO.getOpenType()))
                .map(recordDaHuaDTO -> {
                    return OpenDoorRecordDTO.builder()
                            .projectId(configDTO.getProjectId())
                            .openUserId(this.handleOpenUserId(recordDaHuaDTO))
                            .openDeviceId(recordDaHuaDTO.getChannelCode())
                            .sourceType(this.handleRecordSourceType(recordDaHuaDTO))
                            .arrivalTime(recordDaHuaDTO.getSwingTime())
                            .pictureUrl(recordDaHuaDTO.getRecordImage())
                            .state(recordDaHuaDTO.getOpenResult().shortValue())
                            .type(this.handleRecordType(recordDaHuaDTO.getOpenType()))
                            .direction(this.handleDirection(recordDaHuaDTO.getEnterOrExit()))
                            .approach(AccessApproachEnum.OFF_LINE.getId())
                            .openUserType(this.handleOpenUserType(recordDaHuaDTO))
                            .userName(recordDaHuaDTO.getPersonName()).build();
                }).collect(Collectors.toList());
    }

    private Integer handleOpenUserType(PedestrianRecordDaHuaDTO recordDaHuaDTO) {
        // 62 人脸非法刷门 定义为陌生人，针对人数统计默认人员code
        if (62 == recordDaHuaDTO.getOpenType().intValue()) {
            return OpenUserTypeEnum.INVALID_TYPE.getId();//无效类型
        }
        if(!StringUtils.isEmpty(recordDaHuaDTO.getPersonCode())){
            if(recordDaHuaDTO.getPersonCode().startsWith("HZ")){
                return OpenUserTypeEnum.HZ_TYPE.getId();//海珠局员工
            }
            else if(recordDaHuaDTO.getPersonCode().startsWith("TLD")){
                return OpenUserTypeEnum.ESTATE_TYPE.getId();//物业员工
            }
            else{
                return OpenUserTypeEnum.HEAD_TYPE.getId();//集团员工
            }
        }
        else{
            return OpenUserTypeEnum.INVALID_TYPE.getId();//无效类型
        }
    }

    private String handleOpenUserId(PedestrianRecordDaHuaDTO recordDaHuaDTO) {
        // 62 人脸非法刷门 定义为陌生人，针对人数统计默认人员code
        if (62 == recordDaHuaDTO.getOpenType().intValue()) {
            return UUID.randomUUID().toString();
        }
        return recordDaHuaDTO.getPersonId() == null ? null : recordDaHuaDTO.getPersonId().toString();
    }


    private Short handleRecordType(Integer openType) {
        switch (openType) {
            case 42:
            case 43:
            case 44:
                return AccessTypeEnum.PASS_WORD.getId();
            case 45:
            case 46:
            case 47:
                return AccessTypeEnum.FINGERPRINT.getId();
            case 48:
                return AccessTypeEnum.REMOTE.getId();
            case 49:
                return AccessTypeEnum.BUTTON.getId();
            case 51:
            case 52:
                return AccessTypeEnum.IC_CARD.getId();
            case 60:
            case 61:
            case 62:
                return AccessTypeEnum.FACE.getId();
            case 1434:
                return AccessTypeEnum.QR_CODE.getId();
            default:
                return AccessTypeEnum.OTHER.getId();
        }
    }

    private Integer handleRecordSourceType(PedestrianRecordDaHuaDTO recordDaHuaDTO) {
        // 62 人脸非法刷门 定义为陌生人
        if (62 == recordDaHuaDTO.getOpenType().intValue()) {
            return SourceTypeEnum.STRANGER.type;
        }
        switch (recordDaHuaDTO.getCardType()) {
            case 0:
            case 1:
            case 3:
            case 6:
            case 11:
                return SourceTypeEnum.USER.type;
            case 2:
                return SourceTypeEnum.VISITOR_USER.type;
            default:
                return SourceTypeEnum.STRANGER.type;
        }
    }

    private Short handleDirection(Integer enterOrExit) {
        switch (enterOrExit) {
            case 1:
                return DirectionEnum.IN.getId();
            case 2:
                return DirectionEnum.OUT.getId();
            default:
                return DirectionEnum.UNKNOWN.getId();
        }
    }

    private AuthAccountMapping createUser(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO){
        Integer accountId = pedestrianAuthDTO.getSourceId();
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setId(accountId);
        Account account = accountCentService.getAccount(null, accountQuery);
        if(account == null){
            throw new BusinessException("不存在该人员！");
        }
        AuthAccountMapping authAccountMapping = pedestrianDaHuaHandler.queryUser(account.getPhone(), configDTO);
        if(authAccountMapping != null){
            return authAccountMapping;
        }
        String key = String.format(DaHuaConstant.IDENTITY_KEY,configDTO.getProjectId());
        Integer identityId = (Integer) redisUtils.get(key);
        if(identityId == null){
            List list = pedestrianDaHuaHandler.queryIdentity(configDTO);
            if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(list)){
                identityId = Math.toIntExact(pedestrianDaHuaHandler.createIdentity(configDTO));
            }else {
                JSONObject json = (JSONObject) list.get(0);
                IdentityDaHuaDTO identityDaHuaDTO = json.toJavaObject(IdentityDaHuaDTO.class);;
                identityId = Math.toIntExact(identityDaHuaDTO.getId());
            }
            redisUtils.setWithMinute(key,identityId,DaHuaConstant.IDENTITY_TIME);
        }

        Integer age = account.getAge();
        LocalDateTime localDateTime = LocalDateTime.now();
        if(Objects.nonNull(age)){
            localDateTime = localDateTime.minusYears(age);
        }
        String birthdayNumber = localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String paperNumber = "432524"+birthdayNumber+getFour(accountId.toString());
        String birthday = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        UserDaHuaDTO userDaHuaDTO = UserDaHuaDTO.builder().birthday(birthday)
                .code(GeneralDaHuaHandler.generateOpenCode(account.getId(),configDTO.getProjectId()))
                .deptId(1)
                .name(account.getName())
                .paperNumber(paperNumber)
                .paperType("身份证")
                .status("在职")
                .phone(account.getPhone())
                .sex(account.getSex() == null || account.getSex() == 0 ? "女" : "男")
                .personIdentityId(identityId.toString()).build();
        return pedestrianDaHuaHandler.createUser(configDTO, userDaHuaDTO);
    }

    private static String getFour(String str){
        if(StringUtils.isEmpty(str)){
            return "0000";
        }
        int length = str.length();
        if(length == 4){
            return str;
        }
        if(length < 4){
            StringBuilder strBuilder = new StringBuilder(str);
            for (int i = 0; i < 4 - length; i++) {
                strBuilder.insert(0, "0");
            }
            return strBuilder.toString();
        }
        return str.substring(0, 4);
    }
}
